home *** CD-ROM | disk | FTP | other *** search
-
- require 'chat2.pl'; # into main
- eval "require 'socket.ph'" || eval "require 'sys/socket.ph'"
- || die "socket.ph missing: $!\n";
-
-
- package ftp;
-
- if( defined( &main'PF_INET ) ){
- $pf_inet = &main'PF_INET;
- $sock_stream = &main'SOCK_STREAM;
- local($name, $aliases, $proto) = getprotobyname( 'tcp' );
- $tcp_proto = $proto;
- }
- else {
- $pf_inet = 2;
- $sock_stream = 1;
- $tcp_proto = 6;
- }
-
- $timeout = 30;
-
- $timeout_read = 20 * $timeout;
-
- $timeout_open = $timeout;
-
- $ftp'response = "";
-
- $ftp'ftpbufsize = 4096;
-
- $ftp'hashevery = 1024;
- $ftp'hashnl = 70;
-
- $real_site = "";
-
- $ftp_show = 0;
- sub ftp'debug
- {
- $ftp_show = $_[0];
- }
-
- sub ftp'set_timeout
- {
- $timeout = $_[0];
- $timeout_open = $timeout;
- $timeout_read = 20 * $timeout;
- if( $ftp_show ){
- print STDERR "ftp timeout set to $timeout\n";
- }
- }
-
-
- sub ftp'open_alarm
- {
- die "timeout: open";
- }
-
- sub ftp'timed_open
- {
- local( $site, $ftp_port, $retry_call, $attempts ) = @_;
- local( $connect_site, $connect_port );
- local( $res );
-
- alarm( $timeout_open );
-
- while( $attempts-- ){
- if( $ftp_show ){
- print STDERR "proxy connecting via $proxy_gateway [$proxy_ftp_port]\n" if $proxy;
- print STDERR "Connecting to $site";
- if( $ftp_port != 21 ){
- print STDERR " [port $ftp_port]";
- }
- print STDERR "\n";
- }
-
- if( $proxy ) {
- if( ! $proxy_gateway ) {
- $proxy_gateway = "internet-gateway";
- }
- if( $debug ) {
- print STDERR "using proxy services of $proxy_gateway, ";
- print STDERR "at $proxy_ftp_port\n";
- }
- $connect_site = $proxy_gateway;
- $connect_port = $proxy_ftp_port;
- $real_site = $site;
- }
- else {
- $connect_site = $site;
- $connect_port = $ftp_port;
- }
- if( ! &chat'open_port( $connect_site, $connect_port ) ){
- if( $retry_call ){
- print STDERR "Failed to connect\n" if $ftp_show;
- next;
- }
- else {
- print STDERR "proxy connection failed " if $proxy;
- print STDERR "Cannot open ftp to $connect_site\n" if $ftp_show;
- return 0;
- }
- }
- $res = &ftp'expect( $timeout,
- 120, "service unavailable to $site", 0,
- 220, "ready for login to $site", 1,
- 421, "service unavailable to $site, closing connection", 0);
- if( ! $res ){
- &chat'close();
- next;
- }
- return 1;
- }
- continue {
- print STDERR "Pausing between retries\n";
- sleep( $retry_pause );
- }
- return 0;
- }
-
- sub ftp'open
- {
- local( $site, $ftp_port, $retry_call, $attempts ) = @_;
-
- $SIG{ 'ALRM' } = "ftp\'open_alarm";
-
- local( $ret ) = eval "&timed_open( '$site', $ftp_port, $retry_call, $attempts )";
- alarm( 0 );
-
- if( $@ =~ /^timeout/ ){
- return -1;
- }
- return $ret;
- }
-
- sub ftp'login
- {
- local( $remote_user, $remote_password ) = @_;
-
- if( $proxy ){
- &ftp'send( "USER $remote_user\@$site" );
- }
- else {
- &ftp'send( "USER $remote_user" );
- }
- local( $val ) =
- &ftp'expect($timeout,
- 230, "$remote_user logged in", 1,
- 331, "send password for $remote_user", 2,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 530, "not logged in", 0,
- 332, "account for login not supported", 0,
-
- 421, "service unavailable, closing connection", 0);
- if( $val == 1 ){
- return 1;
- }
- if( $val == 2 ){
- &ftp'send( "PASS $remote_password" );
-
- $val = &ftp'expect( $timeout,
- 230, "$remote_user logged in", 1,
-
- 202, "command not implemented", 0,
- 332, "account for login not supported", 0,
-
- 530, "not logged in", 0,
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 503, "bad sequence of commands", 0,
-
- 421, "service unavailable, closing connection", 0);
- if( $val == 1){
- return 1;
- }
- }
- return 0;
- }
-
- sub ftp'close
- {
- &ftp'quit();
- &chat'close();
- }
-
- sub ftp'cwd
- {
- local( $dir ) = @_;
-
- &ftp'send( "CWD $dir" );
-
- return &ftp'expect( $timeout,
- 200, "working directory = $dir", 1,
- 250, "working directory = $dir", 1,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 502, "command not implemented", 0,
- 530, "not logged in", 0,
- 550, "cannot change directory", 0,
- 421, "service unavailable, closing connection", 0 );
- }
-
- sub ftp'dir_open
- {
- local( $options ) = @_;
- local( $ret );
-
- if( ! &ftp'open_data_socket() ){
- return 0;
- }
-
- if( $options ){
- &ftp'send( "LIST $options" );
- }
- else {
- &ftp'send( "LIST" );
- }
-
- $ret = &ftp'expect( $timeout,
- 150, "reading directory", 1,
-
- 125, "data connection already open?", 0,
-
- 450, "file unavailable", 0,
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 502, "command not implemented", 0,
- 530, "not logged in", 0,
-
- 421, "service unavailable, closing connection", 0 );
- if( ! $ret ){
- &ftp'close_data_socket;
- return 0;
- }
-
-
- accept(NS,S) || die "accept failed $!";
-
- return 1;
- }
-
-
- sub ftp'dir_close
- {
- local( $ret );
-
- $ret = &ftp'expect($timeout,
- 226, "", 1, # transfer complete, closing connection
- 250, "", 1, # action completed
-
- 425, "can't open data connection", 0,
- 426, "connection closed, transfer aborted", 0,
- 451, "action aborted, local error", 0,
- 421, "service unavailable, closing connection", 0);
-
- &ftp'close_data_socket;
-
- if( ! $ret ){
- return 0;
- }
-
- return 1;
- }
-
- sub ftp'quit
- {
- $site_command_check = 0;
- @site_command_list = ();
-
- &ftp'send("QUIT");
-
- return &ftp'expect($timeout,
- 221, "Goodbye", 1, # transfer complete, closing connection
-
- 500, "error quitting??", 0);
- }
-
- sub ftp'read_alarm
- {
- die "timeout: read";
- }
-
- sub ftp'timed_read
- {
- alarm( $timeout_read );
- return sysread( NS, $buf, $ftpbufsize );
- }
-
- sub ftp'read
- {
- $SIG{ 'ALRM' } = "ftp\'read_alarm";
-
- local( $ret ) = eval '&timed_read()';
- alarm( 0 );
-
- if( $@ =~ /^timeout/ ){
- return -1;
- }
- return $ret;
- }
-
- sub ftp'get
- {
- local($rem_fname, $loc_fname, $restart ) = @_;
-
- if ($loc_fname eq "") {
- $loc_fname = $rem_fname;
- }
-
- if( ! &ftp'open_data_socket() ){
- print STDERR "Cannot open data socket\n";
- return 0;
- }
-
- if( $loc_fname ne '-' ){
- local( $restart_at ) = &ftp'filesize( $loc_fname );
- if( $restart && $restart_at > 0 && &ftp'restart( $restart_at ) ){
- $restart = 1;
- chmod( 0644, $loc_fname );
- }
- else {
- $restart = 0;
- unlink( $loc_fname );
- }
- }
-
- &ftp'send( "RETR $rem_fname" );
-
- local( $ret ) =
- &ftp'expect($timeout,
- 150, "receiving $rem_fname", 1,
-
- 125, "data connection already open?", 0,
-
- 450, "file unavailable", 2,
- 550, "file unavailable", 2,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 530, "not logged in", 0,
-
- 421, "service unavailable, closing connection", 0);
- if( $ret != 1 ){
- print STDERR "Failure on RETR command\n";
-
- &ftp'close_data_socket;
-
- return 0;
- }
-
-
- accept(NS,S) || die "accept failed: $!";
-
- if( !open(FH, ($restart ? '>>' : '>') . $loc_fname) ){
- print STDERR "Cannot create local file $loc_fname\n";
-
- &ftp'close_data_socket;
-
- return 0;
- }
-
-
- local( $start_time ) = time;
- local( $bytes, $lasthash, $hashes ) = (0, 0, 0);
- while( ($len = &ftp'read()) > 0 ){
- $bytes += $len;
- if( $strip_cr ){
- $ftp'buf =~ s/\r//g;
- }
- if( $ftp_show ){
- while( $bytes > ($lasthash + $ftp'hashevery) ){
- print STDERR '#';
- $lasthash += $ftp'hashevery;
- $hashes++;
- if( ($hashes % $ftp'hashnl) == 0 ){
- print STDERR "\n";
- }
- }
- }
- if( ! print FH $ftp'buf ){
- print STDERR "\nfailed to write data";
- return 0;
- }
- }
- close( FH );
-
- &ftp'close_data_socket;
-
- if( $len < 0 ){
- print STDERR "\ntimed out reading data!\n";
-
- return 0;
- }
-
- if( $ftp_show ){
- if( $hashes && ($hashes % $ftp'hashnl) != 0 ){
- print STDERR "\n";
- }
- local( $secs ) = (time - $start_time);
- if( $secs <= 0 ){
- $secs = 1; # To avoid a divide by zero;
- }
-
- local( $rate ) = int( $bytes / $secs );
- print STDERR "Got $bytes bytes ($rate bytes/sec)\n";
- }
-
-
- $ret = &ftp'expect($timeout,
- 226, "Got file", 1, # transfer complete, closing connection
- 250, "Got file", 1, # action completed
-
- 110, "restart not supported", 0,
- 425, "can't open data connection", 0,
- 426, "connection closed, transfer aborted", 0,
- 451, "action aborted, local error", 0,
- 421, "service unavailable, closing connection", 0);
-
- return $ret;
- }
-
- sub ftp'delete
- {
- local( $rem_fname, $val ) = @_;
-
- &ftp'send("DELE $rem_fname" );
- $val = &ftp'expect( $timeout,
- 250,"Deleted $rem_fname", 1,
- 550,"Permission denied",0
- );
- return $val == 1;
- }
-
- sub ftp'deldir
- {
- local( $fname ) = @_;
-
- }
-
- sub ftp'put
- {
- local( $loc_fname, $rem_fname ) = @_;
- local( $strip_cr );
-
- if ($loc_fname eq "") {
- $loc_fname = $rem_fname;
- }
-
- if( ! &ftp'open_data_socket() ){
- return 0;
- }
-
- &ftp'send("STOR $rem_fname");
-
-
- local( $ret ) =
- &ftp'expect($timeout,
- 150, "sending $loc_fname", 1,
-
- 125, "data connection already open?", 0,
- 450, "file unavailable", 0,
-
- 532, "need account for storing files", 0,
- 452, "insufficient storage on system", 0,
- 553, "file name not allowed", 0,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 530, "not logged in", 0,
-
- 421, "service unavailable, closing connection", 0);
-
- if( $ret != 1 ){
- &ftp'close_data_socket;
-
- return 0;
- }
-
-
-
- accept(NS,S) || die "accept failed: $!";
-
- if( !open(FH, "<$loc_fname") ){
- print STDERR "Cannot open local file $loc_fname\n";
-
- &ftp'close_data_socket;
-
- return 0;
- }
-
- while (<FH>) {
- print NS ;
- }
- close(FH);
-
- &ftp'close_data_socket;
-
-
- $ret = &ftp'expect($timeout,
- 226, "file put", 1, # transfer complete, closing connection
- 250, "file put", 1, # action completed
-
- 110, "restart not supported", 0,
- 425, "can't open data connection", 0,
- 426, "connection closed, transfer aborted", 0,
- 451, "action aborted, local error", 0,
- 551, "page type unknown", 0,
- 552, "storage allocation exceeded", 0,
-
- 421, "service unavailable, closing connection", 0);
- if( ! $ret ){
- print STDERR "error putting $loc_fname\n";
- }
- return $ret;
- }
-
- sub ftp'restart
- {
- local( $restart_point, $ret ) = @_;
-
- &ftp'send("REST $restart_point");
-
-
- $ret = &ftp'expect($timeout,
- 350, "restarting at $restart_point", 1,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 502, "REST not implemented", 2,
- 530, "not logged in", 0,
- 554, "REST not implemented", 2,
-
- 421, "service unavailable, closing connection", 0);
- return $ret;
- }
-
- sub ftp'type
- {
- local( $type ) = @_;
-
- &ftp'send("TYPE $type");
-
-
- $ret = &ftp'expect($timeout,
- 200, "file type set to $type", 1,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 504, "Invalid form or byte size for type $type", 0,
-
- 421, "service unavailable, closing connection", 0);
- return $ret;
- }
-
- $site_command_check = 0;
- @site_command_list = ();
-
- sub ftp'site_commands
- {
- local( $ret );
-
- if( !$site_command_check ){
-
- $site_command_check = 1;
-
- &ftp'send( "HELP SITE" );
-
- $ret = &ftp'expect( $timeout,
- ".*HELP.*", "", "\$1",
- 214, "", "0",
- 202, "", "0" );
-
- if( $ret eq "0" ){
- print STDERR "No response from HELP SITE\n" if( $ftp_show );
- }
-
- @site_command_list = split(/\s+/, $ret);
- }
-
- return @site_command_list;
- }
-
- sub ftp'pwd
- {
- local( $ret, $cwd );
-
- &ftp'send( "PWD" );
-
-
- $ret = &ftp'expect( $timeout,
- 257, "working dir is", 1,
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 502, "PWD not implemented", 0,
- 550, "file unavailable", 0,
-
- 421, "service unavailable, closing connection", 0 );
- if( $ret ){
- if( $ftp'response =~ /^257\s"(.*)"\s.*$/ ){
- $cwd = $1;
- }
- }
- return $cwd;
- }
-
- sub ftp'mkdir
- {
- local( $path ) = @_;
- local( $ret );
-
- &ftp'send( "MKD $path" );
-
-
- $ret = &ftp'expect( $timeout,
- 257, "made directory $path", 1,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 502, "MKD not implemented", 0,
- 530, "not logged in", 0,
- 550, "file unavailable", 0,
-
- 421, "service unavailable, closing connection", 0 );
- return $ret;
- }
-
- sub ftp'chmod
- {
- local( $path, $mode ) = @_;
- local( $ret );
-
- &ftp'send( sprintf( "SITE CHMOD %o $path", $mode ) );
-
-
- $ret = &ftp'expect( $timeout,
- 200, "chmod $mode $path succeeded", 1,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 502, "CHMOD not implemented", 0,
- 530, "not logged in", 0,
- 550, "file unavailable", 0,
-
- 421, "service unavailable, closing connection", 0 );
- return $ret;
- }
-
- sub ftp'rename
- {
- local( $old_name, $new_name ) = @_;
- local( $ret );
-
- &ftp'send( "RNFR $old_name" );
-
-
- $ret = &ftp'expect( $timeout,
- 350, "", 1,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 502, "RNFR not implemented", 0,
- 530, "not logged in", 0,
- 550, "file unavailable", 0,
- 450, "file unavailable", 0,
-
- 421, "service unavailable, closing connection", 0);
-
-
- if( $ret ) {
- &ftp'send( "RNTO $new_name" );
-
-
- $ret = &ftp'expect( $timeout,
- 250, "rename $old_name to $new_name", 1,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 502, "RNTO not implemented", 0,
- 503, "bad sequence of commands", 0,
- 530, "not logged in", 0,
- 532, "need account for storing files", 0,
- 553, "file name not allowed", 0,
-
- 421, "service unavailable, closing connection", 0);
- }
-
- return $ret;
- }
-
-
- sub ftp'quote
- {
- local( $cmd ) = @_;
-
- &ftp'send( $cmd );
-
- return &ftp'expect( $timeout,
- 200, "Remote '$cmd' OK", 1,
- 500, "error in remote '$cmd'", 0 );
- }
-
-
- sub ftp'expectgot
- {
- ($ftp'response, $ftp'fatalerror) = @_;
- if( $ftp_show ){
- print STDERR "$ftp'response\n";
- }
- }
-
- sub ftp'expect {
- local( $ret );
- local( $time_out );
- local( $expect_args );
-
- $ftp'response = '';
- $ftp'fatalerror = 0;
-
- @expect_args = ();
-
- $time_out = shift(@_);
-
- while( @_ ){
- local( $code ) = shift( @_ );
- local( $pre ) = '^';
- if( $code =~ /^\d/ ){
- $pre =~ "[.|\n]*^";
- }
- push( @expect_args, "$pre(" . $code . " .*)\\015\\n" );
- shift( @_ );
- push( @expect_args,
- "&ftp'expectgot( \$1, 0 ); " . shift( @_ ) );
- }
-
- push( @expect_args, "^(.*)\\015\\n" );
- push( @expect_args, "&ftp'expectgot( \$1, 0 ); 100" );
-
-
- push( @expect_args, 'TIMEOUT' );
- push( @expect_args, "&ftp'expectgot( \"timed out\", 1 ); 0" );
-
- push( @expect_args, 'EOF' );
- push( @expect_args, "&ftp'expectgot( \"remote server gone away\", 1 ); 0" );
-
- if( $ftp_show > 9 ){
- &printargs( $time_out, @expect_args );
- }
-
- $ret = &chat'expect( $time_out, @expect_args );
- if( $ret == 100 ){
- push( @expect_args, "^.*\n" );
- push( @expect_args, "100" );
-
- while( $ret == 100 ){
- $ret = &chat'expect( $time_out, @expect_args );
- }
- }
-
- return $ret;
- }
-
- sub ftp'open_data_socket
- {
- local( $ret );
- local( $hostname );
- local( $sockaddr, $name, $aliases, $proto, $port );
- local( $type, $len, $thisaddr, $myaddr, $a, $b, $c, $d );
- local( $mysockaddr, $family, $hi, $lo );
-
-
- $sockaddr = 'S n a4 x8';
- chop( $hostname = `hostname` );
-
- $port = "ftp";
-
- ($name, $aliases, $proto) = getprotobyname( 'tcp' );
- ($name, $aliases, $port) = getservbyname( $port, 'tcp' );
-
- ($a,$b,$c,$d) = unpack( 'C4', $chat'thisaddr );
-
- $this = $chat'thisproc;
-
- socket(S, $pf_inet, $sock_stream, $proto ) || die "socket: $!";
- bind(S, $this) || die "bind: $!";
-
- $mysockaddr = getsockname(S);
- ($family, $port, $myaddr) = unpack( $sockaddr, $mysockaddr );
-
- $hi = ($port >> 8) & 0x00ff;
- $lo = $port & 0x00ff;
-
- listen( S, 5 ) || die "listen";
-
- &ftp'send( "PORT $a,$b,$c,$d,$hi,$lo" );
-
- return &ftp'expect($timeout,
- 200, "PORT command successful", 1,
- 250, "PORT command successful", 1 ,
-
- 500, "syntax error", 0,
- 501, "syntax error", 0,
- 530, "not logged in", 0,
-
- 421, "service unavailable, closing connection", 0);
- }
-
- sub ftp'close_data_socket
- {
- close(NS);
- }
-
- sub ftp'send
- {
- local($send_cmd) = @_;
- if( $send_cmd =~ /\n/ ){
- print STDERR "ERROR, \\n in send string for $send_cmd\n";
- }
-
- if( $ftp_show ){
- local( $sc ) = $send_cmd;
-
- if( $send_cmd =~ /^PASS/){
- $sc = "PASS <somestring>";
- }
- print STDERR "---> $sc\n";
- }
-
- &chat'print( "$send_cmd\r\n" );
- }
-
- sub ftp'printargs
- {
- while( @_ ){
- print STDERR shift( @_ ) . "\n";
- }
- }
-
- sub ftp'filesize
- {
- local( $fname ) = @_;
-
- if( ! -f $fname ){
- return -1;
- }
-
- return (stat( _ ))[ 7 ];
-
- }
-
- 1;
-